package sel.me.spring.extension;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;

/**
 * spring扩展点
 * @author shenenlu 2021年03月05日 下午15:34:24
 */
public class SpringLifecycleExtension {

    /**
     * MATA-INF/spring.factories
     * interface=class
     */
    ApplicationContextInitializer applicationContextInitializer;
    /**
     * MATA-INF/spring.factories
     * interface=class
     * @Component   @EventListener
     *
     * Spring中提供的标准事件：
     *
     * ContextRefreshEvent，当ApplicationContext容器初始化完成或者被刷新的时候，就会发布该事件。比如调用ConfigurableApplicationContext接口中的refresh()方法。此处的容器初始化指的是所有的Bean都被成功装载，后处理（post-processor）Bean被检测到并且激活，所有单例Bean都被预实例化，ApplicationContext容器已经可以使用。只要上下文没有被关闭，刷新可以被多次触发。XMLWebApplicationContext支持热刷新，GenericApplicationContext不支持热刷新。
     *
     * ContextStartedEvent，当ApplicationContext启动的时候发布事件，即调用ConfigurableApplicationContext接口的start方法的时候。这里的启动是指，所有的被容器管理生命周期的Bean接受到一个明确的启动信号。在经常需要停止后重新启动的场合比较适用。
     *
     * ContextStoppedEvent，当ApplicationContext容器停止的时候发布事件，即调用ConfigurableApplicationContext的close方法的时候。这里的停止是指，所有被容器管理生命周期的Bean接到一个明确的停止信号。
     *
     * ContextClosedEvent，当ApplicationContext关闭的时候发布事件，即调用ConfigurableApplicationContext的close方法的时候，关闭指的是所有的单例Bean都被销毁。关闭上下后，不能重新刷新或者重新启动。
     *
     * RequestHandledEvent，只能用于DispatcherServlet的web应用，Spring处理用户请求结束后，系统会触发该事件。
     */
    ApplicationListener applicationListener;


    ApplicationContextAware applicationContextAware;

    /**
     * MATA-INF/spring.factories
     * interface=class
     */
    EnvironmentPostProcessor environmentPostProcessor;



    /**
     * BeanFactoryPostProcessor可以对bean的定义（配置元数据）进行处理。
     * 也就是说，Spring IoC容器允许BeanFactoryPostProcessor在容器实际实例化任何其它的bean之前读取配置元数据，并有可能修改它
     */
    BeanFactoryPostProcessor beanFactoryPostProcessor;

    BeanPostProcessor beanPostProcessor;

    /**
     * 实现InitializingBean接口
     * 同@PostConstruct, init-method
     *
     */
    InitializingBean initializingBean;

    /**
     * 实现DisposableBean接口
     * 同@PreDestroy, destory-method
     */
    DisposableBean disposableBean;

}
